

import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import utils from './utils'

// 是否存在jsconfig.json
const isExistJsconfig = (projectPath: string) => {
	return fs.existsSync(`${projectPath}jsconfig.json`)
}

// 当按下ctrl或command键执行
function provideDefinition (document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
	const fileName = document.fileName  // 当前文件完整路径
	const workDir = path.dirname(fileName) // 当前文件所在目录
	const line = document.lineAt(position) // 当前光标所在行
	const projectPath = utils.getProjectPath(workDir) // 当前工程目录

	// 夸克组件
	if ((/~/).test(line.text)) {
		// 如果存在jsconfig，就不执行
		if (isExistJsconfig(projectPath)) {
			return
		}

		try {
			// 对当前光标所在行进行 字符串解析，剥离出路径: ~font@1.0 => ['font', '1.0']
			let aliasPathList = line.text.match(/'~[\w\d\@\.]+'/g)?.[0].match(/[a-zA-Z_]+|[\d\.]+/g)
			let [comName = '', version] = [aliasPathList?.[0], aliasPathList?.[1]]

			// 项目工程中的夸克工程
			let quarkList = JSON.parse(fs.readFileSync(`${projectPath}quark.cfg.json`, 'utf8')).quark

			// 遍历夸克工程
			for (const quarkProject of quarkList) {
				// 夸克组件路由
				let routeConfig = JSON.parse(fs.readFileSync(`${projectPath}node_modules/@fql/${quarkProject}/route_config/module_map.json`, 'utf8'))
				// 组件路由映射路径是否在组件路由文件存在
				let componentName = routeConfig[comName] || ''
				// 如果存在映射路径，则跳转
				if (componentName) {
					// 组件路径
					let destPath = `${projectPath}node_modules/@fql/${quarkProject}/libs/${componentName}/${version}/${componentName}.js`
					destPath = fs.existsSync(destPath) ? destPath : `${projectPath}node_modules/@fql/${quarkProject}/libs/${componentName}/${version}/index.js`

					// 如果存在
					if (fs.existsSync(destPath)) {
						// new vscode.Position(0, 0) 表示跳转到某个文件的第一行第一列
						return new vscode.Location(vscode.Uri.file(destPath), new vscode.Position(0, 0))
					}
				}
			}
		} catch (error) {
			vscode.window.showErrorMessage('跳转错误' + error)
		}

	}

	// atom组件
	if ((/#/).test(line.text)) {
		// 如果存在jsconfig，就不执行
		if (isExistJsconfig(projectPath)) {
			return
		}

		try {
			// 对当前光标所在行进行 字符串解析，剥离出路径: #logic_weex/position/1.0 => ['logic_weex', 'position', '1.0']
			let aliasPathList = line.text.match(/'#[\w\d\/\.]+'/g)?.[0].match(/[a-zA-Z_]+|[\d\.]+/g)
			let [atomPartName = '', comName = '', version] = [aliasPathList?.[0], aliasPathList?.[1], aliasPathList?.[2]]

			// 项目工程中的atom工程
			let atomList = JSON.parse(fs.readFileSync(`${projectPath}quark.cfg.json`, 'utf8')).atom
			// 匹配的atom工程
			let atomName = atomList.find((v: string) => v.includes(atomPartName))

			// atom组件路由文件
			let routeConfig = JSON.parse(fs.readFileSync(`${projectPath}node_modules/@fql/${atomName}/route_config/module_map.json`, 'utf8'))
			// 组件映射名
			let componentName = routeConfig[comName] || ''

			// 如果存在组件映射名，则跳转
			if (componentName) {
				// 组件路径
				let destPath = `${projectPath}node_modules/@fql/${atomName}/libs/${componentName}/${version}/${componentName}.js`
				destPath = fs.existsSync(destPath) ? destPath : `${projectPath}node_modules/@fql/${atomName}/libs/${componentName}/${version}/index.js`

				// 如果存在
				if (fs.existsSync(destPath)) {
					return new vscode.Location(vscode.Uri.file(destPath), new vscode.Position(0, 0))
				}
			}
		} catch (error) {
			vscode.window.showErrorMessage('跳转错误' + error)
		}
	}

	// 工程组件
	if ((/%/).test(line.text)) {
		try {
			// 对当前光标所在行进行 字符串解析，剥离出路径: %font@1.0 => ['font', '1.0']
			let aliasPathList = line.text.match(/'%[\w\d\(@|\/)\.]+'/g)?.[0].match(/[a-zA-Z_]+|[\d\.]+/g)
			let [comName = '', version] = [aliasPathList?.[0], aliasPathList?.[1]]

			// 项目工程中的路由文件
			let routeConfig = JSON.parse(fs.readFileSync(`${projectPath}src/components/route_config.json`, 'utf8'))
			// 组件映射名
			let componentName = routeConfig[comName] || ''

			// 如果存在组件映射名，则跳转
			if (componentName) {
				// 组件路径
				let destPath = `${projectPath}src/components/${componentName}/${version}/${componentName}.js`
				destPath = fs.existsSync(destPath) ? destPath : `${projectPath}src/components/${componentName}/${version}/index.js`

				// 如果存在
				if (fs.existsSync(destPath)) {
					return new vscode.Location(vscode.Uri.file(destPath), new vscode.Position(0, 0))
				}
			}

		} catch (error) {
			vscode.window.showErrorMessage('跳转错误' + error)
		}

	}

	// 工程组件
	if ((/@/).test(line.text)) {
		try {
			// 对当前光标所在行进行 字符串解析，剥离出路径: @/api/activity/auto_sale.js => ['@', '/api/activity/auto_sale.js']
			let aliasPathList = line.text.match(/(@\/[^'"]+)/g)?.[0].match(/@|[^@]+/g)
			let [char = '', partPath] = [aliasPathList?.[0], aliasPathList?.[1]]
			// 如果存在partPath
			if (partPath) {
				// 组件路径
				let destPath = `${projectPath}src${(/\.[^.]+$/).test(partPath) ? partPath : partPath + '.js'}`

				// 如果存在
				if (fs.existsSync(destPath)) {
					return new vscode.Location(vscode.Uri.file(destPath), new vscode.Position(0, 0))
				}
			}
		} catch (error) {
			vscode.window.showErrorMessage('跳转错误' + error)
		}

	}
}

export function activate (context: vscode.ExtensionContext) {
	console.log('fit-link跳转插件激活成功！')

	let language = vscode.languages.registerDefinitionProvider(['javascript'], {
		provideDefinition
	})

	context.subscriptions.push(language)
}

// This method is called when your extension is deactivated
export function deactivate () { }
